package cn.com.cifi.mars.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.com.cifi.mars.bean.bo.PortalTodoBo;
import cn.com.cifi.mars.bean.dto.MymContractDto;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.entity.DmOdsMyVsMarsSContract;
import cn.com.cifi.mars.entity.DmOdsMyVsMarsSContractLog;
import cn.com.cifi.mars.entity.DmOdsMyVsMarsSContractTmp;
import cn.com.cifi.mars.entity.MymVsMarsSContract;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.entity.common.SysDictionary;
import cn.com.cifi.mars.mapper.mars.DmOdsMyVsMarsSContractMapper;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.DmOdsMyVsMarsSContractLogService;
import cn.com.cifi.mars.service.DmOdsMyVsMarsSContractService;
import cn.com.cifi.mars.service.DmOdsMyVsMarsSContractTmpService;
import cn.com.cifi.mars.service.IdmUserService;
import cn.com.cifi.mars.service.MymVsMarsSContractService;
import cn.com.cifi.mars.service.SysDictionaryService;
import cn.com.cifi.mars.util.ListUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.SysLogUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author plx
 * @since 2019-12-17
 */
@Slf4j
@Service
public class DmOdsMyVsMarsSContractServiceImpl extends ServiceImpl<DmOdsMyVsMarsSContractMapper, DmOdsMyVsMarsSContract> implements DmOdsMyVsMarsSContractService {
    @Autowired
    private MymVsMarsSContractService mymVsMarsSContractService;
    @Autowired
    private DmOdsMyVsMarsSContractLogService dmOdsMyVsMarsSContractLogService;
    @Autowired
    private DmOdsMyVsMarsSContractTmpService dmOdsMyVsMarsSContractTmpService;
    @Autowired
    private DmOdsMyVsMarsSContractMapper dmOdsMyVsMarsSContractMapper;
    @Autowired
    private IdmUserService idmUserService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private SysDictionaryService sysDictionaryService;

    @Override
    public void syncMyContract() {
        //清空
        remove(new QueryWrapper<>());
        log.info("清空DmOdsMyVsMarsSContract数据完毕");

        LocalDateTime now = LocalDateTime.now();

        //同步
        log.info("同步DmOdsMyVsMarsSContract数据开始");
        int batch = 5000;

        List<MymVsMarsSContract> list = mymVsMarsSContractService.list();
		List<List> tempList = ListUtils.getSubList(list, batch);
		
		int i = 0;
		for (List<MymVsMarsSContract> _list : tempList) {
			i++;
			List<MymVsMarsSContract> subList = (List<MymVsMarsSContract>) _list;
            List<DmOdsMyVsMarsSContract> tmp = subList.parallelStream()
                    .map(x -> {
                        DmOdsMyVsMarsSContract dest = new DmOdsMyVsMarsSContract();

                        dest.setEtlUpdateTime(now);
                        dest.setEtlCreateTime(now);
                        try {
                            PropertyUtils.copyProperties(dest, x);
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        }
                        return dest;
                    }).collect(Collectors.toList());
            saveBatch(tmp);
        }
        log.info("同步DmOdsMyVsMarsSContract数据结束");
    }

    /**
     * 增量同步
     */
    @Override
    public void syncIncrement() {
        log.info("同步DmOdsMyVsMarsSContract增量数据开始");

        //清空临时表数据
        dmOdsMyVsMarsSContractTmpService.remove(new QueryWrapper<>());
        log.info("同步DmOdsMyVsMarsSContract增量数据->清空临时表数据");

        //查最大更新时间
        QueryWrapper<DmOdsMyVsMarsSContract> queryWrapper = new QueryWrapper();
        queryWrapper.select("max(ModifiedTime) ModifiedTime");
        List<DmOdsMyVsMarsSContract> list = list(queryWrapper);
        LocalDateTime maxModifiedTime = list.isEmpty()?null:list.get(0).getModifiedTime();
        log.info("同步DmOdsMyVsMarsSContract增量数据->查最大更新时间：{}",maxModifiedTime);

        //查明源视图增量数据
        QueryWrapper<MymVsMarsSContract> mymVsMarsSContractQueryWrapper = new QueryWrapper<>();
        if (maxModifiedTime != null){
            mymVsMarsSContractQueryWrapper.gt("ModifiedTime",maxModifiedTime);
        }
        List<MymVsMarsSContract> mymVsMarsSContractList = mymVsMarsSContractService.list(mymVsMarsSContractQueryWrapper);
        
        if(CollectionUtils.isNotEmpty(mymVsMarsSContractList)) {
        	//发送预警门户代办
            sendWarningPortalTodo(mymVsMarsSContractList);
            //去重
            mymVsMarsSContractList = mymVsMarsSContractList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MymVsMarsSContract::getContractGUID))), ArrayList::new));
            
            int batch = 3000;
            List<List> tempList = ListUtils.getSubList(mymVsMarsSContractList, batch);

            LocalDateTime createTime = LocalDateTime.now();
            String serialNo = UUIDUtils.create();
            int i = 0;
            for (List<MymVsMarsSContract> _list : tempList) {
                i++;
                List<MymVsMarsSContract> subList = _list;
                List<DmOdsMyVsMarsSContractLog> logs = subList.stream()
                        .map(x -> {
                            DmOdsMyVsMarsSContractLog dest = new DmOdsMyVsMarsSContractLog();
                            dest.setLogCreateTime(createTime);
                            dest.setLogSerialNo(serialNo);
                            try {
                                PropertyUtils.copyProperties(dest, x);
                            } catch (Exception e) {
                                log.error(e.getMessage(), e);
                            }
                            return dest;
                        }).collect(Collectors.toList());
                dmOdsMyVsMarsSContractLogService.saveBatch(logs);
                List<DmOdsMyVsMarsSContractTmp> tmp = subList.parallelStream()
                        .map(x -> {
                            DmOdsMyVsMarsSContractTmp dest = new DmOdsMyVsMarsSContractTmp();
                            try {
                                PropertyUtils.copyProperties(dest, x);
                            } catch (Exception e) {
                                log.error(e.getMessage(), e);
                            }
                            return dest;
                        }).collect(Collectors.toList());
                dmOdsMyVsMarsSContractTmpService.saveBatch(tmp);
            }
            //比较并更新到DmOdsMyVsMarsSContract
            baseMapper.mergeInto();
        }
        syncIncrement2();
        log.info("同步DmOdsMyVsMarsSContract增量数据结束");
    }
    
    public void syncIncrement2() {
        //清空临时表数据
        dmOdsMyVsMarsSContractTmpService.remove(new QueryWrapper<>());
        log.info("同步DmOdsMyVsMarsSContract增量数据->清空临时表数据");
        String  lastTimeString = LocalDateTimeUtils.getLastByFormat(30, "yyyy-MM-dd HH:mm:ss");
        //查最大更新时间
        QueryWrapper<DmOdsMyVsMarsSContract> queryWrapper = new QueryWrapper();
        queryWrapper.eq("Status", "激活").gt("ModifiedTime",lastTimeString).isNull("YwgsDate");
        List<DmOdsMyVsMarsSContract> list = list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list)) {
        	List<String> contractGUIDList = list.stream().map(s -> s.getContractGUID()).collect(Collectors.toList());
            //查明源视图增量数据
            QueryWrapper<MymVsMarsSContract> mymVsMarsSContractQueryWrapper = new QueryWrapper<>();
            mymVsMarsSContractQueryWrapper.in("ContractGUID", contractGUIDList).isNotNull("YwgsDate");
            List<MymVsMarsSContract> mymVsMarsSContractList = mymVsMarsSContractService.list(mymVsMarsSContractQueryWrapper);
            
            if(CollectionUtils.isNotEmpty(mymVsMarsSContractList)) {
            	//发送预警门户代办
                sendWarningPortalTodo(mymVsMarsSContractList);
                //去重
                mymVsMarsSContractList = mymVsMarsSContractList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MymVsMarsSContract::getContractGUID))), ArrayList::new));
                
                int batch = 3000;
                List<List> tempList = ListUtils.getSubList(mymVsMarsSContractList, batch);

                LocalDateTime createTime = LocalDateTime.now();
                String serialNo = UUIDUtils.create();
                int i = 0;
                for (List<MymVsMarsSContract> _list : tempList) {
                    i++;
                    List<MymVsMarsSContract> subList = _list;
                    List<DmOdsMyVsMarsSContractLog> logs = subList.stream()
                            .map(x -> {
                                DmOdsMyVsMarsSContractLog dest = new DmOdsMyVsMarsSContractLog();
                                dest.setLogCreateTime(createTime);
                                dest.setLogSerialNo(serialNo);
                                try {
                                    PropertyUtils.copyProperties(dest, x);
                                } catch (Exception e) {
                                    log.error(e.getMessage(), e);
                                }
                                return dest;
                            }).collect(Collectors.toList());
                    dmOdsMyVsMarsSContractLogService.saveBatch(logs);
                    List<DmOdsMyVsMarsSContractTmp> tmp = subList.parallelStream()
                            .map(x -> {
                                DmOdsMyVsMarsSContractTmp dest = new DmOdsMyVsMarsSContractTmp();
                                try {
                                    PropertyUtils.copyProperties(dest, x);
                                } catch (Exception e) {
                                    log.error(e.getMessage(), e);
                                }
                                return dest;
                            }).collect(Collectors.toList());
                    dmOdsMyVsMarsSContractTmpService.saveBatch(tmp);
                }

                //比较并更新到DmOdsMyVsMarsSContract
                baseMapper.mergeInto();
            }
        }
        
    }

    public void sendWarningPortalTodo(List<MymVsMarsSContract> mymVsMarsSContractList) {
        List<String> contractGUIDList = mymVsMarsSContractList.stream().
                collect(Collectors.groupingBy(MymVsMarsSContract::getContractGUID, Collectors.counting()))
                .entrySet().stream()
                .filter(entry -> entry.getValue() > 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        if(CollectionUtils.isEmpty(contractGUIDList)){
            return;
        }
        SysLogUtils.addSysLog(LogEventEnum.BROWSE,"明源签约数据","增量同步明源签约数据",mymVsMarsSContractList.toString());
        SysLogUtils.addSysLog(LogEventEnum.BROWSE,"明源签约数据","重复的明源签约数据id",contractGUIDList.toString());

        PortalTodoBo todoBo = new PortalTodoBo("明源同步数据重复异常","重复数据：" + contractGUIDList);

        List<SysDictionary> sysDictionaryList = sysDictionaryService.selectListByTypeCode("mym_synchronization_error_warning");
        List<String> aliasList = sysDictionaryList.stream().map(SysDictionary::getDictValue).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(aliasList)){
            return;
        }
        List<IdmUser> userList = idmUserService.getByAliasList(aliasList);
        List<String> instanceIdList = commonService.sendMessagePortalTodo(todoBo, userList);

        SysLogUtils.addSysLog(LogEventEnum.BROWSE,"明源签约数据","明源签约数据重复,发送代办","发送用户 " + userList + ",代办id " + instanceIdList);
    }

    @Override
    public List<MymContractDto> selectNewestContractsByProjectFid(String kingdeeProjectfId) {
        return dmOdsMyVsMarsSContractMapper.selectNewestContractsByProjectFid(kingdeeProjectfId);
    }

    public List<MymContractDto> selectMymContractList(List<String> bldPrdIDs) {
        List<MymContractDto>list=dmOdsMyVsMarsSContractMapper.selectMymContractList(bldPrdIDs);
        return list;
    }

    @Override
    public List<MymContractDto> selectMymContractListOfActivate(List<String> buildList) {
        List<MymContractDto> list=  dmOdsMyVsMarsSContractMapper.queryMymContractBybuildList(buildList);
        return list;
    }

    @Override
    public List<MymContractDto> selectByKingdeexmprojguid(String kingdeexmprojguid) {
        return  dmOdsMyVsMarsSContractMapper.selectByKingdeexmprojguid(kingdeexmprojguid);
    }

    @Override
    public void syncByEsbData(List<DmOdsMyVsMarsSContract> contractList) {
        LocalDateTime createTime = LocalDateTime.now();
        String serialNo = UUIDUtils.create();
        List<DmOdsMyVsMarsSContractLog> logs = contractList.stream()
                .map(x -> {
                    DmOdsMyVsMarsSContractLog dest = new DmOdsMyVsMarsSContractLog();
                    dest.setLogCreateTime(createTime);
                    dest.setLogSerialNo(serialNo);
                    try {
                        PropertyUtils.copyProperties(dest, x);
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                    return dest;
                }).collect(Collectors.toList());
        dmOdsMyVsMarsSContractLogService.saveBatch(logs);
        
        //清空临时表数据
        dmOdsMyVsMarsSContractTmpService.remove(new QueryWrapper<>());
        
        List<DmOdsMyVsMarsSContractTmp> tmp = contractList.parallelStream()
                .map(x -> {
                    DmOdsMyVsMarsSContractTmp dest = new DmOdsMyVsMarsSContractTmp();
                    try {
                        PropertyUtils.copyProperties(dest, x);
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                    return dest;
                }).collect(Collectors.toList());
        dmOdsMyVsMarsSContractTmpService.saveBatch(tmp);

        //比较并更新到DmOdsMyVsMarsSContract
        baseMapper.mergeInto();
    }

}
